package com.gykj.admin.config;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.core.RedisTemplate;

import com.alibaba.fastjson.JSON;

/**
 * Created by lmx on 2017/9/25.
 * 这里实现CachingConfigurerSupport主要是方便使用自定义keyGenerator
 */
@Configuration
@EnableCaching //启用缓存
public class MybatisCacheConfig  extends CachingConfigurerSupport {

    @Autowired
    public RedisTemplate<String,Object> redisTemplate;

    private static final Log log = LogFactory.getLog(MybatisCacheConfig.class);
    /**
     * 配置redis缓存管理对象
     * @return
     */
    @Bean(name = "MybatisCacheManager")
    @Override
    public CacheManager cacheManager() {
        log.info("初始化MybatisCacheManager");
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        MybatisCache.setRedisTemplate(redisTemplate);
        return cacheManager;
    }

    /**
	 * redis key生成策略
	 * target: 类
	 * method: 方法
	 * params: 参数
	 * @return KeyGenerator
	 * 注意: 该方法只是声明了key的生成策略,还未被使用,需在@Cacheable注解中指定keyGenerator
	 *      如: @Cacheable(value = "key", keyGenerator = "cacheKeyGenerator")
	 */

    @Bean
    public KeyGenerator cacheKeyGenerator() {
        return (target, method, params) -> {
            StringBuilder sb = new StringBuilder();
            sb.append(target.getClass().getName());
            sb.append(method.getName());
            for (Object obj : params) {
            	// 由于参数可能不同, hashCode肯定不一样, 缓存的key也需要不一样
                sb.append(JSON.toJSONString(obj).hashCode());
            }
            return sb.toString();
        };
    }
}
